//! 
//! Tcp Socket 客户端
//! 主要与服务端进行通信和数据传输
//! 
//! tcp_client.rs
//! 
//! (RUST) alone
//! 
//! Create time: 2025-09-23		alone
//! Update time: 2025-09-29		alone
//! 

use std::{io::Cursor, sync::{atomic::{AtomicBool, Ordering}, Arc}};
use anyhow::{anyhow, Ok};
use prost::bytes::Buf;
use tokio::{io::{AsyncReadExt, AsyncWriteExt}, net::{tcp, TcpStream}, sync::{broadcast, Mutex}};
use tracing::{error, info};
use uuid::Uuid;

use crate::{common::{pubsub::Subscribe, transport::{Connector, FrameSink, Shutdown}}, net::{data_package::DataPackage, head::{ProtocolHead, HEAD_SIZE_EXCEPT_VERIFY, VERIFY_MAGIC}, NetEvent}};

/// socket 客户端
#[derive(Debug, Clone)]
pub struct TcpClient 
{
	/// 广播订阅事件
	tx_evt: broadcast::Sender<NetEvent>,
	/// 写数据
    writer: Arc<Mutex<Option<tcp::OwnedWriteHalf>>>,
	/// 读数据
	reader: Arc<Mutex<Option<tcp::OwnedReadHalf>>>,
	/// 是否已连接
	is_connected: Arc<AtomicBool>,
	/// 连接地址
    address: Arc<std::sync::Mutex<String>>,
	/// uuid
	uuid: Arc<std::sync::Mutex<Uuid>>,
}

impl TcpClient 
{
	pub fn new(address: String)
		-> Self
	{
		let (tx, _) = tokio::sync::broadcast::channel(100);
		Self 
		{ 
			tx_evt: tx, 
			writer: Arc::new(Mutex::new(None)), 
			reader: Arc::new(Mutex::new(None)), 
			is_connected: Arc::new(AtomicBool::new(false)), 
			address: Arc::new(std::sync::Mutex::new(address)),
			uuid: Arc::new(std::sync::Mutex::new(Uuid::new_v4())),
		}
	}

	pub async fn set_writer(&self, writer: tcp::OwnedWriteHalf)
	{
		*self.writer.lock().await = Some(writer);
	}

	pub async fn set_reader(&self, reader: tcp::OwnedReadHalf)
	{
		*self.reader.lock().await = Some(reader);
	}

	pub async fn set_event(&mut self, event: broadcast::Sender<NetEvent>)
	{
		self.tx_evt = event
	}

	/// 设置已连接
	pub fn mark_connected(&self)
	{
		self.is_connected.store(true, Ordering::Release);
	}

	/// 设置未连接
	pub fn mark_disconnected(&self)
	{
		self.is_connected.store(false, Ordering::Release);
	}

	pub fn address(&self) 
		-> String 
	{
		let addr = self.address.lock().unwrap_or_else(
			|e| e.into_inner());
        return addr.clone();
	}

	pub fn uuid(&self)
		-> Uuid
	{
		let uid = self.uuid.lock().unwrap_or_else(
			|e| e.into_inner());
        return uid.clone();
	}

	pub fn start(&self)
	{
		let oneself = self.clone();

		tokio::spawn(async move 
			{
				let result = oneself.recv().await;
				match result 
				{
					Result::Ok(()) =>
					{
						info!("正常退出SocketClient!");
					}
					Result::Err(e) =>
					{
						error!("{e}");
						// 发送客户端断开连接信号
						let _ = oneself.tx_evt.send(NetEvent::Disconnected(oneself.clone()));
					}
				}
			}
		);
	}
}

impl Subscribe for TcpClient
{
	type Event = NetEvent;

	fn subscribe(&self) -> 
		broadcast::Receiver<Self::Event> 
	{
		self.tx_evt.subscribe()	
	}
}

impl Connector for TcpClient 
{
	async fn connect(&self) 
		-> anyhow::Result<()> 
	{
		if self.is_connected()
		{
			return Ok(())
		}

		let addr = self.address();
		match TcpStream::connect(addr.clone()).await
        {
            Result::Ok(stream) => 
            {
                // 读写分离
                let (reader, writer) = stream.into_split();

				{
					*self.writer.lock().await = Some(writer);
				}
				
				{
					*self.reader.lock().await = Some(reader);
				}
				self.start();
				self.mark_connected();
                Ok(())
            }
            Result::Err(e) => 
            {
				let _ = self.tx_evt.send(NetEvent::ConnectedFailed);
                Err(anyhow!("连接服务器地址 -> {} 失败, Error: {}", addr, e))
            }
        }
	}

	fn is_connected(&self) 
		-> bool 
	{
		self.is_connected.load(std::sync::atomic::Ordering::Relaxed)
	}
}

impl FrameSink for TcpClient 
{
	async fn send(&self, frame: &[u8]) 
		-> anyhow::Result<()> 
	{
		if !self.is_connected()
		{
			return Err(anyhow!("不能向未连接的地址写数据！"));
		}

		let mut guard_writer = self.writer.lock().await;

		match guard_writer.as_mut() 
		{
			Some(writer) =>
			{
				if let Err(e) = writer.write_all(&frame).await 
				{
					return Err(anyhow!("{}", e));
				}

				return Ok(());
			}
			None => 
			{
				return Err(anyhow!("不能向 writer 为 None 的地址写数据！"));
			}
		}
	}

	async fn recv(&self) 
		-> anyhow::Result<()>
	{
		let mut is_error = false;
		let mut err_str = String::new();
		let addr = self.address();
		match self.reader.lock().await.as_mut()
		{
			Some(reader) => 
			{
				while self.is_connected()
				{
					let mut verify = [0u8; 2];
					
					if let Err(e) = reader.read_exact(&mut verify).await 
					{
						is_error = true;
						err_str = format!("读取地址来自[{addr}]的数据失败，错误: {e} :(");
						break;
					}

					let mut cursor = Cursor::new(&verify);
					let verify = cursor.get_u16_le();
					if verify != VERIFY_MAGIC
					{
						continue
					}

					// 读取头部剩余字节
					let mut head_residue = [0u8; HEAD_SIZE_EXCEPT_VERIFY];
					if let Err(e) = reader.read_exact(&mut head_residue).await 
					{
						is_error = true;
						err_str = format!("读取地址来自[{addr}]发送的数据失败，错误: {e} :(");
						break;
					}

					// 封装头部
					let head = ProtocolHead::replica(
						verify, 
						cursor.get_u8(), 
						cursor.get_u8(), 
						cursor.get_u32_le(), 
						);
					
					// 获取数据
					let mut data = vec![0u8; head.len as usize];
					if head.len != 0
					{
						if let Err(e) = reader.read_exact(&mut data).await 
						{
							is_error = true;
							err_str = format!("读取地址来自[{addr}]发送的数据失败，错误: {e} :(");
							break;
						}
					}

					// 封装数据
					let data_pacage = DataPackage::new(head, data, self.clone());
					let _ = self.tx_evt.send(NetEvent::RecvData(data_pacage));
				}
			}
			None => 
			{ 
				is_error = true;
				err_str = format!("Address -> {}, reader 是 None。", addr);
			}
		}

		self.mark_disconnected();

		if is_error
		{
			return Err(anyhow!("{err_str}"))
		}

		Ok(())
	}
}

impl Shutdown for TcpClient 
{
	async fn close(&self) 
		-> anyhow::Result<()> 
	{
		self.mark_disconnected();
		let _ = self.writer.lock().await.take();
        let _ = self.reader.lock().await.take();
		Ok(())
	}	
}